/*
 * vim:foldmethod=marker:
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <assert.h>

#define N_MAX	300

struct adjlist {
	struct Node	*first;
	struct Node	*last;
	int		size;
	uint8_t		used;
	int		color;
	long long	d; //distance from 's' to this vertex
	int		prev;
	int		heap_idx;
};

struct Node {
	int		x;
	long long	weight;
	int		index;
	char		is_queued;
	struct Node	*next;
};

struct edge {
	int		a, b;
	long long	weight;
	int		index;
};

struct prio_queue {
	struct edge	*array;
	int		size;
	int		size_max;
};

struct mst {
	int		*edges;
	long long	tree_weight;
	int		n, size;
};

/*****************************************************************************/

#define SWAP_INT(a, b)	(((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b)))
#define MIN(a, b)	((a) < (b) ? (a) : (b))
#define MAX(a, b)	((a) > (b) ? (a) : (b))

// {{{ adjlist interface functions
static void
pushback(struct adjlist *al, int x, int weight, int idx)
{
	struct Node *newnode;

	newnode = (struct Node *) calloc(1UL, sizeof (struct Node));
	newnode->x         = x;
	newnode->weight    = weight;
	newnode->next      = NULL;
	newnode->is_queued = 0;
	newnode->index     = idx;
	if (!al->first)
		al->first = newnode;
	else
		al->last->next = newnode;
	al->last = newnode;
	al->size++;
}

static void
free_al(struct adjlist *al)
{
	struct Node *n, *p;
	p = n = al->first;
	while (n) {
		n = n->next;
		free(p);
		p = n;
	}
}
// }}}

// {{{ priority queue
static void
pq_destroy(struct prio_queue *pq)
{
	if (pq->size_max) free(pq->array);
}

static void
Heap__sift_down(struct prio_queue *pq, int start)
{
	int parent = start,
	    child,
	    swap;

	while (parent * 2 + 1 < pq->size) {
		child = parent * 2 + 1;
		swap = parent;

		if (pq->array[parent].weight > pq->array[child].weight) {
			swap = child;
			#ifdef DEBUG2
			fprintf(stderr, "Heap__sift_down(): parent=%d child=%d, swap=%d ; pq->array[parent].weight=%d pq->array[child].weight=%d\n",
					parent, child, swap, pq->array[parent].weight, pq->array[child].weight);
			#endif
		}

		if (child+1 < pq->size &&
		    pq->array[swap].weight > pq->array[child+1].weight)
			swap = child+1;

		if (swap != parent) {
			SWAP_INT(pq->array[parent].a, pq->array[swap].a);
			SWAP_INT(pq->array[parent].b, pq->array[swap].b);
			SWAP_INT(pq->array[parent].weight, pq->array[swap].weight);
			SWAP_INT(pq->array[parent].index, pq->array[swap].index);
			parent = swap;
		} else {
			return;
		}
	}
}

static void
Heap__sift_up(struct prio_queue *pq, int start, int end)
{
	register int child = end, parent = (end - 1) / 2;

	/*
	 * 'start' is a kind of left barrier for this function
	 */
        while (child > start)
		if (pq->array[(child - 1) / 2].weight > pq->array[child].weight) {
			SWAP_INT(pq->array[parent].a, pq->array[child].a);
			SWAP_INT(pq->array[parent].b, pq->array[child].b);
			SWAP_INT(pq->array[parent].weight, pq->array[child].weight);
			SWAP_INT(pq->array[parent].index, pq->array[child].index);

			child = parent;
			parent = (child - 1) / 2;
		} else {
			break;
		}
}

static void
Heap__heapify(struct prio_queue *pq)
{
	register int start = pq->size / 2 - 1;

	while (start >= 0)
		Heap__sift_down(pq, start--);
}

static struct edge
pq_extract_min(struct prio_queue *pq)
{
	SWAP_INT(pq->array[0].a, pq->array[pq->size-1].a);
	SWAP_INT(pq->array[0].b, pq->array[pq->size-1].b);
	SWAP_INT(pq->array[0].weight, pq->array[pq->size-1].weight);
	SWAP_INT(pq->array[0].index, pq->array[pq->size-1].index);
	--pq->size;
	Heap__sift_down(pq, 0);

	return pq->array[pq->size];
}

static void
pq_init(struct prio_queue *pq, const int n)
{
	pq->array = (struct edge *) calloc(8, sizeof *pq->array);
	pq->size = 0;
	pq->size_max = 8;
}

static void
pq_insert(struct prio_queue *pq, const int a_idx, const int b_idx,
		const int weight, const int index)
{
	struct edge *tmp;

	if (pq->size + 1 > pq->size_max) {
		tmp = (struct edge *) realloc(pq->array, (sizeof *tmp) * (pq->size_max *= 2));
		if (tmp == NULL) {
			fprintf(stderr, "failed to realloc pq->array (new size = %d)\n",
					pq->size_max);
			assert(tmp != NULL);
		} else
			pq->array = tmp;
	}

	pq->array[pq->size].a = a_idx;
	pq->array[pq->size].b = b_idx;
	pq->array[pq->size].weight = weight;
	pq->array[pq->size].index  = index;
	if (pq->array[pq->size].a > pq->array[pq->size].b)
		SWAP_INT(pq->array[pq->size].a, pq->array[pq->size].b);
	pq->size += 1;

	Heap__sift_up(pq, 0, pq->size - 1);
}

static unsigned char
pq_is_empty(struct prio_queue *pq)
{
	return (pq->size ? 0 : 1);
}

static void
pq_print(struct prio_queue *pq, char *delim)
{
	register int i = 0;

	for (i = 0; i < pq->size; i++)
		fprintf(stderr, "i=%5d: { a=%d b=%d weight=%lld }%s", i,
			pq->array[i].a, pq->array[i].b, pq->array[i].weight, delim);
	putchar('\n');
}
// }}}

static void
mst_add_node(struct mst *T, const int edge_idx)
{
	int *tmp = NULL;

	if (T->size == 0) {
		T->edges = (int *) calloc(1UL<<4, sizeof *T->edges);
		T->size  = 8;
	}
	if (T->n + 2 >= T->size) {
		tmp = (int *) realloc(T->edges, (T->size *= 2) * sizeof *T->edges);
		if (tmp)
			T->edges = tmp;
		else {
			fprintf(stderr, " failed to realloc T->edges (new size = %d)\n", T->size);
			exit(EXIT_FAILURE);
		}
	}
	T->edges[T->n++] = edge_idx;
}

static void
mst_print(struct mst *T)
{
	int i = 0;

	printf("%lld\n", T->tree_weight);
	while (i < T->n)
		printf("%d\n", T->edges[i++] + 1);
}

static void
mst_destroy(struct mst *t)
{
	if (t->size) free(t->edges);
	t->size = 0;
}

/* extern int
edgecmp(const void *p1, const void *p2)
{
	const struct edge *e1 = (const struct edge *) p1, *e2 = (const struct edge *) p2;

	if (e1->weight < e2->weight)
		return -1;
	if (e1->weight > e2->weight)
		return 1;
	if (e1->a < e2->a)
		return -1;
	if (e1->a > e2->a)
		return 1;
	if (e1->b < e2->b)
		return -1;
	return 0;
} */

extern int
kruskal(int **am, int *color, int **edge_idxs, int *used, const int n, struct mst *T)
{
	struct Node *node;
	register int i = 0;
	int j = 0;
	struct prio_queue pq;
	struct edge e;
	//struct edge *E;
	char ttl = 0;
	/* struct llist {
		struct llist *prev;
		int index;
		struct llist *next;
	} **cs;
	int *cs_index;

	cs = (struct llist **) calloc((unsigned long) n, sizeof *cs);
	cs_index = (int *) calloc((long) n, sizeof *cs_index); */
	pq_init(&pq, n);

	for (i = 0; i < n; ++i)
		color[i] = i;

	for (j = 0; j < n; ++j)
		for (i = j; i < n; ++i)
			if (am[j][i])
				pq_insert(&pq, j, i, am[j][i], 0);

	while (!pq_is_empty(&pq)) {
		e = pq_extract_min(&pq);
	#ifdef DEBUG
		fprintf(stderr, "e = { a=%d b=%d weight=%lld index=%d}\n", 
			e.a + 1, e.b + 1, e.weight, e.index);
	#endif
		if (color[e.a] != color[e.b]) {
		#ifdef DEBUG
			fprintf(stderr, "\tcolor[e.a]=%d != color[e.b]=%d\n"
				"\tT->tree_weight=%lld  +=  am[e.b][e.a]=%d\n",
				color[e.a], color[e.b],
				T->tree_weight, am[e.b][e.a]);
		#endif
			mst_add_node(T, edge_idxs[e.b][e.a]);
			T->tree_weight += am[e.b][e.a];

			if (used[e.a] && used[e.b]) {
				fprintf(stderr, "  ·\t(used[e.a=%d] && used[e.b=%d]) == 1 "
					"--merging connected spaces - O(n)\n",
					e.a + 1, e.b + 1);
				for (i = 0; i < n; ++i)
					if (color[i] == color[e.b])
						color[i] = color[e.a];
			} else if (used[e.a]) {
				used[e.b] = 1;
				color[e.b] = color[e.a];
			} else if (used[e.b]) {
				used[e.a] = 1;
				color[e.a] = color[e.b];
			} else {
				used[e.a] = used[e.b] = 1;
				color[e.b] = color[e.a];
			}
		}
	#ifdef DEBUG
		putc('\n', stderr);
	#endif
	}
	/* i = 0;
	while (E[i].index != -1) {
		if (color[E[i].a] != color[E[i].b]) {
			mst_add_node(T, edge_idxs[E[i].b][E[i].a]);
			T->tree_weight += am[E[i].b][E[i].a];
			if (color[E[i].a] < color[E[i].b])
				color[E[i].b] = color[E[i].a];
			else
				color[E[i].a] = color[E[i].b];
		}
		++i;
	} */

	for (j = 0; j < n && !ttl; ++j)
		for (i = 0; i < n && !ttl; ++i)
			if (color[j] != color[i]) {
			#ifdef DEBUG
				fprintf(stderr, "EГГOГ: color[%d]=%d != color[%d]=%d\n",
					j + 1, color[j], i + 1, color[i]);
			#endif
				T->n = 0;
				T->tree_weight = -1LL;

				ttl = 1; break;
			}

	pq_destroy(&pq);
	return 0;
}

int
main(void)
{
	int **am, n, *color, m, **edge_idxs, *used;
	int i = 0;
	struct mst T;
	int a, b, w;
	struct edge *E;

	scanf("%d%d", &n, &m);
	color = (int *) calloc((unsigned long) n, sizeof *color);
	used = (int *) calloc((unsigned long) n, sizeof *color);
	am = (int **) malloc(n * sizeof *am);
	edge_idxs = (int **) malloc(n * sizeof *edge_idxs);
	T.n = T.size = T.tree_weight = 0;
	//E = (struct edge *) calloc(m + 1UL, sizeof *E);
	while (i < n)
		am[i] = (int *) calloc((unsigned long) n, sizeof **am),
			edge_idxs[i++] = (int *) calloc((unsigned long) n,
					sizeof **edge_idxs);

	i = 0;
	while (i < m) {
		scanf("%d%d%d", &a, &b, &w);
		--a,b--;
		am[a][b] = am[b][a] = w;
		edge_idxs[a][b] = edge_idxs[b][a] = i;
	/*	E[i].a = MIN(a, b);
		E[i].b = MAX(a, b);
		E[i].weight = w;
		E[i].index  = i; */
		++i;
	}
	//E[m].weight = E[m].a = E[m].b = E[m].index = -1;
	//qsort(E, 1UL + m, sizeof *E, edgecmp);

	kruskal(am, color, edge_idxs, used, n, &T);
	mst_print(&T);

	mst_destroy(&T);
	for (i = 0; i < n; ++i)
		free(am[i]), free(edge_idxs[i]);
	free(am);
	free(edge_idxs);
	free(color);
	free(used);
	return 0;
}
